package com.chhuang.ewcrm.thread;

import com.chhuang.ewcrm.App;
import com.chhuang.ewcrm.bean.CameraBean;
import com.chhuang.ewcrm.bean.QYStatusBean;
import com.chhuang.ewcrm.config.PropertiesUtil;
import com.chhuang.ewcrm.cons.Constants;
import com.chhuang.ewcrm.dao.WLicensePlateDao;
import com.chhuang.ewcrm.dao.WLprCameraDao;
import com.chhuang.ewcrm.entity.WLicensePlate;
import com.chhuang.ewcrm.entity.WLprCamera;
import com.chhuang.ewcrm.frame.CameraFrame;
import com.chhuang.ewcrm.qy.QYNetSDK;
import com.chhuang.ewcrm.qy.QYStatusCode;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.examples.win32.W32API;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ComboBox;
import net.sdk.bean.serviceconfig.imagesnap.Data_T_ImageUserInfo;
import net.sdk.bean.serviceconfig.imagesnap.Data_T_PicInfo;
import net.sdk.function.serviceoperation.platedevice.callback.Callback_FGetImageCbEx;
import net.sdk.function.systemcommon.imagesnap.callback.Callback_FGetImageCBEx;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.*;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.zip.InflaterInputStream;

import static javafx.application.Platform.runLater;

/**
 * 打开车牌识别摄像头
 * @author chhuang
 * @create 2020-10-12-15:15
 */
public class InitLPRCameraThread implements Runnable {
    private final Logger logger = LoggerFactory.getLogger(InitLPRCameraThread.class);

    //芊熠车牌识别SDK
    private static QYNetSDK qyNetSDK;

    //摄像头对像
    private final List<CameraBean> cameraBeans = new LinkedList<CameraBean>();

    private final ComboBox<WLicensePlate> lprComboBox;

    private final InitCtrlCommThread ctrlCommThread;

    private static int lprTHandle = -1;//当前识别成功的摄像头thandle

    private final WLprCameraDao wLprCameraDao = App.getSession().getMapper(WLprCameraDao.class);

    public InitLPRCameraThread(ComboBox<WLicensePlate> lprComboBox, InitCtrlCommThread ctrlCommThread){
        this.lprComboBox = lprComboBox;
        this.ctrlCommThread = ctrlCommThread;
    }

    @Override
    public void run() {
        initQY();
    }

    private void initQY(){
        //获取配置信息如果开启了车牌识别功能
        WLprCamera wlprca = new WLprCamera();
        wlprca.setCameraEnable(true);
        List<WLprCamera> wLprCameras = wLprCameraDao.query(wlprca);

        if(wLprCameras!=null && !wLprCameras.isEmpty()){
            javax.swing.SwingUtilities.invokeLater(()-> {
                int cameraNum = wLprCameras.size();
                CameraFrame cameraFrame = CameraFrame.getCameraFrame(cameraNum);

                //初始化
                qyNetSDK = QYNetSDK.INSTANCE;
                QYStatusBean qyStatusBean = QYStatusCode.getStatusCode(qyNetSDK.Net_Init(), "Net_Init()");
                if(!qyStatusBean.isSuccess()){
                    logger.debug(qyStatusBean.getResult());
                    return;
                }

                for (WLprCamera wLprCamera : wLprCameras){
                    Panel panelRealplay = new Panel();
                    panelRealplay.setBackground(new Color(255,114,86));
                    cameraFrame.addLprCamerasPanel(panelRealplay);

                    CameraBean cameraBean = new CameraBean(wLprCamera);

                    //添加摄像头
                    int tHandle = qyNetSDK.Net_AddCamera(cameraBean.getIp());
                    cameraBean.setTHandle(tHandle);
                    if(tHandle>=0){
                        //连接摄像头, timeout单位秒
                        int status = qyNetSDK.Net_ConnCamera(tHandle, cameraBean.getPort(), (short) 10);
                        qyStatusBean = QYStatusCode.getStatusCode(status,"Net_ConnCamera");
                        cameraBean.setConnStatus(qyStatusBean.isSuccess());
                        if(qyStatusBean.isSuccess()){
                            W32API.HWND hwnd = new W32API.HWND(Native.getComponentPointer(panelRealplay));
                            //tHandle相机句柄,niStreamType码流类型 0主码流 1辅码流, hWnd窗口句柄
                            //打开预览
                            status = qyNetSDK.Net_StartVideo(tHandle, 0, hwnd);
                            qyStatusBean = QYStatusCode.getStatusCode(status,"Net_StartVideo");
                            cameraBean.setVideoStatus(qyStatusBean.isSuccess());
                            if(!qyStatusBean.isSuccess()){
                                logger.debug(qyStatusBean.getResult());
                            }

                            //设置车牌识别
                            /*status = qyNetSDK.Net_RegOffLineImageRecvEx(tHandle, this.fCb, Pointer.NULL);
                            qyStatusBean = QYStatusCode.getStatusCode(status,"Net_RegOffLineImageRecvEx");
                            cameraBean.setLprStatus(qyStatusBean.isSuccess());
                            if(!qyStatusBean.isSuccess()){
                                logger.debug(qyStatusBean.getResult());
                            }*/
                            //设置车牌识别
                            status = qyNetSDK.Net_RegImageRecvEx(tHandle, this.fCb, Pointer.NULL);
                            qyStatusBean = QYStatusCode.getStatusCode(status,"Net_RegImageRecvEx");
                            cameraBean.setLprStatus(qyStatusBean.isSuccess());
                            if(!qyStatusBean.isSuccess()){
                                logger.debug(qyStatusBean.getResult());
                            }
                        }else {
                            logger.debug(qyStatusBean.getResult());
                        }
                    }else{
                        logger.debug("无效句柄，添加摄像头失败");
                    }

                    logger.debug(cameraBean.toString());
                    cameraBeans.add(cameraBean);
                }
            });
        }
    }

    /**
     * 关闭
     */
    public void close(){
        if(!cameraBeans.isEmpty()){
            for(CameraBean cameraBean : cameraBeans){
                if(cameraBean!=null){
                    if(cameraBean.isVideoStatus()){
                        qyNetSDK.Net_StopVideo(cameraBean.getTHandle());
                    }
                    if(cameraBean.isConnStatus()){
                        qyNetSDK.Net_DisConnCamera(cameraBean.getTHandle());
                    }
                    if(cameraBean.getTHandle()>=0){
                        qyNetSDK.Net_DelCamera(cameraBean.getTHandle());
                    }
                }
            }
            qyNetSDK.Net_UNinit();
        }
        CameraFrame.exit();
    }

//    private Callback_FGetImageCbEx.FGetImageCbEx fCb = new Callback_FGetImageCbEx.FGetImageCbEx() {
//        public int invoke(int tHandle, int uiImageId, Data_T_ImageUserInfo.T_ImageUserInfo.ByReference ptImageInfo, Data_T_PicInfo.T_PicInfo.ByReference ptPicInfo, Pointer pUserData) {
//            try {
//                String szLprResult = new String(ptImageInfo.szLprResult, "GB2312");
//                logger.debug("查询结果：\n - 车牌号：" + szLprResult +
//                        "\n - 车牌类型：" + ptImageInfo.ucLprType + "\n - 车牌颜色：" +
//                        ptImageInfo.ucPlateColor);
//                runLater(()-> lprComboBox.setValue(szLprResult));
//            }
//            catch (UnsupportedEncodingException e){
//                e.printStackTrace();
//            }
//            return 0;
//        }
//    };

    private Callback_FGetImageCBEx.FGetImageCBEx fCb = new Callback_FGetImageCBEx.FGetImageCBEx() {
        public int invoke(int tHandle, int uiImageId, Data_T_ImageUserInfo.T_ImageUserInfo.ByReference ptImageInfo, Data_T_PicInfo.T_PicInfo.ByReference ptPicInfo, Pointer pUserData) {
            try {
                String szLprResult = new String(ptImageInfo.szLprResult, "GB2312").trim();

                logger.debug("查询结果：\n - 车牌号：" + szLprResult +
                        "\n - 车牌类型：" + ptImageInfo.ucLprType + "\n - 车牌颜色：" +
                        ptImageInfo.ucPlateColor);

                runLater(()-> {
                    boolean flag = true;
                    WLicensePlate temp = lprComboBox.getValue();
                    if(temp!=null && StringUtils.isNotEmpty(temp.getWlpNumber())){
                        flag = false;
                        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                        alert.setTitle("车牌识别");
                        alert.setHeaderText("识别到另一辆车，是否要修改为新车牌号？");
                        alert.setContentText("识别到的新车牌号："+szLprResult+"，原输入框存在车牌号："+temp.getWlpNumber());
                        Optional<ButtonType> result = alert.showAndWait();
                        if(result.get() == ButtonType.OK){
                            flag = true;
                        }
                    }
                    if(flag)
                        lprComboBox.getSelectionModel().select(lprComboBox.getConverter().fromString(szLprResult));
                });
                ctrlLight(tHandle, false);
                lprTHandle = tHandle;
            }
            catch (UnsupportedEncodingException e){
                e.printStackTrace();
            }
            return 0;
        }
    };

    /**
     * 控制红绿灯
     * @param tHandle
     * @param finish
     */
    private void ctrlLight(int tHandle, boolean finish){
        switch (tHandle) {
            case -1: break;
            case 0:
                if(finish) ctrlCommThread.lingt2Green(); else ctrlCommThread.lingt2Red();
                break;
            case 1:
                if(finish) ctrlCommThread.lingt1Green(); else ctrlCommThread.lingt1Red();
                break;
        }
    }

    /**
     *称重完成，绿灯放行
     */
    public void finishWeigh(){
        ctrlLight(lprTHandle, true);
    }

}
